package org.example.zuul.http;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.example.zuul.filter.ZuulFilter;
import org.example.zuul.filter.ZuulProperties;
import org.example.zuul.filter.post.SendResponseFilter;
import org.example.zuul.filter.pre.RequestWrapperFilter;
import org.example.zuul.filter.route.RoutingFilter;

public class ZuulRunner {
    private final ConcurrentMap<String, List<ZuulFilter>> hashFiltersByType = new ConcurrentHashMap<>();

    public void init(Collection<ZuulProperties.ZuulRoute> routes) {
        hashFiltersByType.put(ZuulFilter.TYPE_PRE, new ArrayList<>(Collections.singletonList(new RequestWrapperFilter(routes))));
        hashFiltersByType.put(ZuulFilter.TYPE_ROUTE, new ArrayList<>(Collections.singletonList(new RoutingFilter())));
        hashFiltersByType.put(ZuulFilter.TYPE_POST, new ArrayList<>(Collections.singletonList(new SendResponseFilter())));
    }

    public void routeInit(HttpServletRequest request, HttpServletResponse response) {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.setRequest(request);
        ctx.setResponse(response);
    }

    public void preRoute() throws Exception {
        runFilters(ZuulFilter.TYPE_PRE);
    }

    public void route() throws Exception {
        runFilters(ZuulFilter.TYPE_ROUTE);
    }

    public void postRoute() throws Exception {
        runFilters(ZuulFilter.TYPE_POST);
    }

    public void runFilters(String type) throws Exception {
        List<ZuulFilter> list = this.hashFiltersByType.get(type);
        if (list != null) {
            for (ZuulFilter zuuFilter : list) {
                zuuFilter.run();
            }
        }
    }
}
